package com.example.demo.hutool.redis;


import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;
import redis.clients.jedis.JedisPubSub;

import java.util.concurrent.*;

public class JedisSubscribe {

    public static void main(String[] args) throws InterruptedException {
        ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(1, 1, 0, TimeUnit.HOURS, new ArrayBlockingQueue<>(1));
        extracted(threadPoolExecutor);
//        while (true){
//            boolean terminated = threadPoolExecutor.isTerminated();
//            int corePoolSize = threadPoolExecutor.getCorePoolSize();
//            boolean terminating = threadPoolExecutor.isTerminating();
//
//        }

    }

    private static void extracted(ThreadPoolExecutor threadPoolExecutor) {
        JedisPubSub jedisPubSub = new JedisPubSub() {
            @Override
            public void onMessage(String channel, String message) {
                System.out.println("onMessage" + "---" + channel + ":" + message);
                try {
                    Thread.sleep(9000);
                } catch (InterruptedException e) {
                    throw new RuntimeException(e);
                }
                if (message.equals("kkk")) {
                    throw new RuntimeException("myException");
                }
            }

            @Override
            public void onPUnsubscribe(String pattern, int subscribedChannels) {
                System.out.println("onPUnsubscribe" + "---" + pattern + ":" + subscribedChannels);
            }

            @Override
            public void onPMessage(String pattern, String channel, String message) {
                System.out.println("onPMessage" + "---" + pattern + "-----" + channel + "-----" + message);
            }

            @Override
            public void onSubscribe(String channel, int subscribedChannels) {
                System.out.println("onSubscribe" + "---" + channel + ":" + subscribedChannels);
            }
        };

        //建并执行一个在给定初始延迟后首次启用的定期操作，随后，在每一次执行终止和下一次执行开始之间都存在给定的延迟。如果任务的任一执行遇到异常
        // ，就会取消后续执行。否则，只能通过执行程序的取消或终止方法来终止该任务。


        Runnable runnable = new Runnable() {
            int sleepTime = 0;
            int maxSleepTimeSecond = 1000;

            @Override
            public void run() {

                while (true) {
                    JedisPool jedisPool = RedisTypeTest.getJedisPool();
                    Jedis jedis = null;
                    try {
                        jedis = jedisPool.getResource();
                        System.out.println("jedis资源获取成功");
                        jedis.clientSetname("channel1-sxm");
                        String[] strings = {"sxm", "mxs"};
                        // 订阅频道消息
//                        jedis.subscribe(jedisPubSub, strings);
                        // jedis.psubscribe(jedisPubSub, "__key*__:*");所有通知
                     //   jedis.psubscribe(jedisPubSub, "__keyevent@0__:*");//指定库的所有通知  类型 key  AKE
                        jedis.psubscribe(jedisPubSub, "__keyspace@0__:*");//指定库的所有 key 类型     AKE
                    } catch (Exception e) {
                        if (jedis != null) {
                            jedis.close();
                        }
                        if (sleepTime < maxSleepTimeSecond) {
                            sleepTime = sleepTime + 20;
                        }
                        if (sleepTime >= 100) {
                            try {
                                Thread.sleep(sleepTime);
                                System.out.println("睡眠" + sleepTime);
                            } catch (Exception ex) {
                                System.out.println("睡眠异常" + e.getMessage());
                            }
                        }
                        System.out.println("异常，等待重试" + e.getMessage());
                    }
                }

            }
        };

        threadPoolExecutor.execute(runnable);
    }

    //继承
    class Subscribe extends JedisPubSub {
        @Override
        public void onMessage(String channel, String message) {
            System.out.println("onMessage" + "---" + channel + ":" + message);
        }

        @Override
        public void onSubscribe(String channel, int subscribedChannels) {
            System.out.println("onSubscribe" + "---" + channel + ":" + subscribedChannels);
        }
    }
}